package net.goutalk.glcs.module.erpModel.caseErpMaterial.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.enums.YesOrNoEnum;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.module.erpModel.caseErpLog.entity.CaseErpLog;
import net.goutalk.glcs.module.erpModel.caseErpLog.service.ICaseErpLogService;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.dto.MaterialHistoryPageDto;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.dto.StockCountDto;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.entity.CaseErpMaterial;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.mapper.CaseErpMaterialMapper;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.service.ICaseErpMaterialService;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.vo.CaseErpInstoreLogVo;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.vo.CaseErpOutstoreLogVo;
import net.goutalk.glcs.module.erpModel.caseErpMaterial.vo.MaterialHistoryPageVo;
import net.goutalk.glcs.module.erpModel.caseErpStore.entity.CaseErpStoreReceipt;
import net.goutalk.glcs.module.erpModel.caseErpStore.entity.CaseErpStoreReceiptDetail;
import net.goutalk.glcs.module.erpModel.caseErpStore.mapper.CaseErpStoreReceiptDetailMapper;
import net.goutalk.glcs.module.erpModel.caseErpStore.mapper.CaseErpStoreReceiptMapper;
import net.goutalk.glcs.module.organization.entity.User;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class CaseErpMaterialServiceImpl extends MPJBaseServiceImpl<CaseErpMaterialMapper, CaseErpMaterial> implements ICaseErpMaterialService {

    private final ICaseErpLogService caseErpLogService;

    private final CaseErpStoreReceiptDetailMapper caseErpStoreReceiptDetailMapper;

    private final CaseErpStoreReceiptMapper caseErpStoreReceiptMapper;

    @Override
    public String getCodeNumber() {
        //数据库中查流水号
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String format = formatter.format(new Date());
        String s = format.replaceAll("-", "");
        String system = "mat" + s;
        int[] ints = NumberUtil.generateRandomNumber(0, 9, 9);
        String s1 = Arrays.toString(ints).replace("[","").replace("]","").replaceAll(",", "").replaceAll(" ","").trim();
        return system+s1.trim();
    }

    @Override
    public Boolean stockCount(StockCountDto dto) {
        CaseErpMaterial caseErpMaterial = this.getById(dto.getId());
        CaseErpLog log = new CaseErpLog();
        CaseErpStoreReceiptDetail caseErpStoreReceiptDetail = new CaseErpStoreReceiptDetail();
        caseErpStoreReceiptDetail.setName(caseErpMaterial.getName());
        caseErpStoreReceiptDetail.setCode(caseErpMaterial.getCode());
        caseErpStoreReceiptDetail.setModel(caseErpMaterial.getModel());
        caseErpStoreReceiptDetail.setCount(dto.getCount());
        if (dto.getType() == YesOrNoEnum.YES.getCode()){
            caseErpMaterial.setInventory(caseErpMaterial.getInventory().add(dto.getCount()));
            //修改库存详情表数据
            caseErpStoreReceiptDetail.setOperateType(1);
            caseErpStoreReceiptDetail.setLocalInventory(caseErpMaterial.getInventory());//当前库存
            log.setExecuteResultJson("盘点增加"+dto.getCount()+"库存");
        }else if (dto.getType() == YesOrNoEnum.NO.getCode()){
            caseErpMaterial.setInventory(caseErpMaterial.getInventory().subtract(dto.getCount()));
            //修改库存详情表数据
            caseErpStoreReceiptDetail.setOperateType(0);
            caseErpStoreReceiptDetail.setLocalInventory(caseErpMaterial.getInventory());
            log.setExecuteResultJson("盘点报废"+dto.getCount()+"库存");
        }else {
            caseErpMaterial.setInventory(caseErpMaterial.getInventory().subtract(dto.getCount()));
            //修改库存详情表数据
            caseErpStoreReceiptDetail.setOperateType(-1);
            caseErpStoreReceiptDetail.setLocalInventory(caseErpMaterial.getInventory());
            log.setExecuteResultJson("盘点减少"+dto.getCount()+"库存");
        }
        caseErpStoreReceiptDetailMapper.insert(caseErpStoreReceiptDetail);
        this.updateById(caseErpMaterial);

        log.setKeyId(dto.getId());
        log.setCategoryId(1);
        log.setOperateTime(LocalDateTime.now());
        User user = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_INFO_KEY, new User());
        log.setOperateUserAccount(user.getName());
        caseErpLogService.save(log);

        return true;
    }

    @Override
    public PageOutput<MaterialHistoryPageVo> getMaterialHistoryPage(MaterialHistoryPageDto dto) {
        CaseErpMaterial caseErpMaterial = this.getById(dto.getId());
        List<CaseErpStoreReceiptDetail> caseErpStoreReceiptDetailList = new ArrayList<>();
        List<MaterialHistoryPageVo> materialHistoryPageVoList = new ArrayList<>();
        if (StrUtil.isNotBlank(caseErpMaterial.getCode())){//全部
            caseErpStoreReceiptDetailList = caseErpStoreReceiptDetailMapper.selectList(Wrappers.<CaseErpStoreReceiptDetail>query().lambda()
                    .eq(CaseErpStoreReceiptDetail::getCode,caseErpMaterial.getCode()).orderByDesc(CaseErpStoreReceiptDetail::getCreateDate));
            materialHistoryPageVoList = BeanUtil.copyToList(caseErpStoreReceiptDetailList, MaterialHistoryPageVo.class);
            if (CollectionUtil.isNotEmpty(materialHistoryPageVoList)){
                for (MaterialHistoryPageVo materialHistoryPageVo : materialHistoryPageVoList) {//操作类型：-1：减少、0：报废、1：增加、2：销售订单、3：采购订单
                    if (ObjectUtil.isNotEmpty(materialHistoryPageVo.getOperateType()) && materialHistoryPageVo.getOperateType() == -1){
                        materialHistoryPageVo.setOperateTypeName("盘点减少");
                        materialHistoryPageVo.setType(YesOrNoEnum.NO.getCode());
                        materialHistoryPageVo.setTypeName("出库");
                    }else if (ObjectUtil.isNotEmpty(materialHistoryPageVo.getOperateType()) && materialHistoryPageVo.getOperateType() == 0){
                        materialHistoryPageVo.setOperateTypeName("盘点报废");
                        materialHistoryPageVo.setTypeName("出库");
                        materialHistoryPageVo.setType(YesOrNoEnum.NO.getCode());
                    }else if (ObjectUtil.isNotEmpty(materialHistoryPageVo.getOperateType()) && materialHistoryPageVo.getOperateType() == 1){
                        materialHistoryPageVo.setOperateTypeName("盘点增加");
                        materialHistoryPageVo.setTypeName("入库");
                        materialHistoryPageVo.setType(YesOrNoEnum.YES.getCode());
                    }else if (ObjectUtil.isNotEmpty(materialHistoryPageVo.getOperateType()) && materialHistoryPageVo.getOperateType() == 2){
                        materialHistoryPageVo.setOperateTypeName("销售订单");
                        materialHistoryPageVo.setTypeName("出库");
                        materialHistoryPageVo.setType(YesOrNoEnum.NO.getCode());
                    }else if (ObjectUtil.isNotEmpty(materialHistoryPageVo.getOperateType()) && materialHistoryPageVo.getOperateType() == 3){
                        materialHistoryPageVo.setOperateTypeName("采购订单");
                        materialHistoryPageVo.setTypeName("入库");
                        materialHistoryPageVo.setType(YesOrNoEnum.YES.getCode());
                    }
                }
            }
        }
        if (ObjectUtil.isNotEmpty(dto.getType()) && dto.getType() == YesOrNoEnum.YES.getCode()){//入库
            materialHistoryPageVoList = materialHistoryPageVoList.stream().filter(x->ObjectUtil.isNotEmpty(x.getType()) && x.getType().equals(YesOrNoEnum.YES.getCode())).collect(Collectors.toList());
        }else if (ObjectUtil.isNotEmpty(dto.getType()) && dto.getType() == YesOrNoEnum.NO.getCode()){//出库
            materialHistoryPageVoList = materialHistoryPageVoList.stream().filter(x->ObjectUtil.isNotEmpty(x.getType()) && x.getType().equals(YesOrNoEnum.NO.getCode())).collect(Collectors.toList());
        }

        PageOutput<MaterialHistoryPageVo> output = new PageOutput<>();
        output.setCurrentPage(dto.getLimit());
        output.setPageSize(dto.getSize());
        output.setTotal(materialHistoryPageVoList.size());
        output.setList(materialHistoryPageVoList);

        return output;
    }

    @Override
    public List<CaseErpInstoreLogVo> checkMaterialInstore(String code) {
        //查询出入库详情表相关数据
        List<CaseErpStoreReceiptDetail> caseErpStoreReceiptDetailList = caseErpStoreReceiptDetailMapper.selectList(Wrappers.<CaseErpStoreReceiptDetail>query().lambda()
                .eq(CaseErpStoreReceiptDetail::getCode,code).eq(CaseErpStoreReceiptDetail::getOperateType,3));//入库为采购订单数据
        List<CaseErpStoreReceipt> caseErpStoreReceiptList = caseErpStoreReceiptMapper.selectList(Wrappers.<CaseErpStoreReceipt>query());
        List<CaseErpInstoreLogVo> caseErpInstoreLogVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(caseErpStoreReceiptDetailList)){
            for (CaseErpStoreReceiptDetail caseErpStoreReceiptDetail : caseErpStoreReceiptDetailList) {
                if (ObjectUtil.isNotEmpty(caseErpStoreReceiptDetail.getStoreReceiptId())){
                    CaseErpStoreReceipt caseErpStoreReceipt = caseErpStoreReceiptList.stream().filter(x -> x.getId().equals(caseErpStoreReceiptDetail.getStoreReceiptId())).findFirst().orElse(new CaseErpStoreReceipt());
                    CaseErpInstoreLogVo caseErpInstoreLogVo = new CaseErpInstoreLogVo();
                    caseErpInstoreLogVo.setId(caseErpStoreReceipt.getId());
                    caseErpInstoreLogVo.setNumber(caseErpStoreReceipt.getCode());
                    caseErpInstoreLogVo.setTheme(caseErpStoreReceipt.getName());
                    caseErpInstoreLogVo.setDate(caseErpStoreReceipt.getCreateDate());
                    caseErpInstoreLogVo.setPerson(caseErpStoreReceipt.getPersonNames());
                    caseErpInstoreLogVo.setCount(caseErpStoreReceiptDetail.getCount());
                    caseErpInstoreLogVo.setInsertType("入库单");
                    caseErpInstoreLogVo.setStore("原料库A01");
                    caseErpInstoreLogVoList.add(caseErpInstoreLogVo);
                }
            }
        }
        return caseErpInstoreLogVoList;
    }

    @Override
    public List<CaseErpOutstoreLogVo> checkMaterialOutStore(String code) {
        //查询出入库详情表相关数据
        List<CaseErpStoreReceiptDetail> caseErpStoreReceiptDetailList = caseErpStoreReceiptDetailMapper.selectList(Wrappers.<CaseErpStoreReceiptDetail>query().lambda()
                .eq(CaseErpStoreReceiptDetail::getCode,code).eq(CaseErpStoreReceiptDetail::getOperateType,2));//出库为销售订单数据
        List<CaseErpStoreReceipt> caseErpStoreReceiptList = caseErpStoreReceiptMapper.selectList(Wrappers.<CaseErpStoreReceipt>query());
        List<CaseErpOutstoreLogVo> caseErpOutstoreLogVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(caseErpStoreReceiptDetailList)){
            for (CaseErpStoreReceiptDetail caseErpStoreReceiptDetail : caseErpStoreReceiptDetailList) {
                if (ObjectUtil.isNotEmpty(caseErpStoreReceiptDetail.getStoreReceiptId())){
                    CaseErpStoreReceipt caseErpStoreReceipt = caseErpStoreReceiptList.stream().filter(x -> x.getId().equals(caseErpStoreReceiptDetail.getStoreReceiptId())).findFirst().orElse(new CaseErpStoreReceipt());
                    CaseErpOutstoreLogVo caseErpOutstoreLogVo = new CaseErpOutstoreLogVo();
                    caseErpOutstoreLogVo.setId(caseErpStoreReceipt.getId());
                    caseErpOutstoreLogVo.setNumber(caseErpStoreReceipt.getCode());
                    caseErpOutstoreLogVo.setTheme(caseErpStoreReceipt.getName());
                    caseErpOutstoreLogVo.setDate(caseErpStoreReceipt.getCreateDate());
                    caseErpOutstoreLogVo.setPerson(caseErpStoreReceipt.getPersonNames());
                    caseErpOutstoreLogVo.setCount(caseErpStoreReceiptDetail.getCount());
                    caseErpOutstoreLogVo.setOutType("出库单");
                    caseErpOutstoreLogVo.setStore("原料库A01");
                    caseErpOutstoreLogVoList.add(caseErpOutstoreLogVo);
                }
            }
        }
        return caseErpOutstoreLogVoList;
    }


}
